<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="所属工厂" prop="parentId">
        <el-tree-select
            v-model="queryParams.deptId"
            :data="deptOptions"
            :props="{ value: 'deptId', label: 'deptName', children: 'children' }"
            value-key="deptId"
            placeholder="选择所属工厂"
            check-strictly
            clearable
            @change="handleChangeFactory"
        >
        </el-tree-select>
      </el-form-item>
      <el-form-item label="选择设备" prop="devs">
        <el-select :placeholder="'已选择'+checkedOptions.length+'个设备'">
          <template #empty >
            <div style="width: 332px; height: 374px;" class="DropDownPopBox">
              <div style="margin-bottom: 5px">
                <el-input v-model="searchValue" @change="searchDev" :suffix-icon="Search" placeholder="请输入设备名称"/>
              </div>
              <div>
                <el-scrollbar height="270px">
                  <p v-for="i in devs" style="margin: 0;padding: 0">
                    <el-checkbox-group @change="selectDev" v-model="checkedOptions">
                      <el-checkbox style="height: 17px;font-size: 12px" :label="i" size="default" >{{i.name}}</el-checkbox>
                    </el-checkbox-group>
                  </p>
                </el-scrollbar>
              </div>
              <div>
                <el-pagination
                    layout="total, prev, pager, next"
                    :total="selectPageTotal"
                    :page-size="selectPageOption.pageSize"
                    :current-page="selectPageOption.pageNum"
                    @current-change="handleSelectPageChange"
                />
              </div>
            </div>

          </template>
        </el-select>
      </el-form-item>
      <el-form-item label="创建时间" style="width: 308px">
        <el-date-picker
            v-model="daterangeCreateTime"
            value-format="YYYY-MM-DD"
            type="daterange"
            range-separator="-"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
        ></el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-card shadow="never">
      <div id="chart-middle" style="height: 350px;width: 100%"></div>
    </el-card>
    <el-row :gutter="10" class="mb8 mt10">
      <el-col :span="1.5">
        <el-button
            type="warning"
            plain
            icon="Download"
            @click="handleExport"
            v-hasPermi="['business:transaction:export']"
        >导出
        </el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
    <el-tabs
        type="card"
        class="demo-tabs"
        @tab-click="handleClick"
        v-model="activeTab"
    >
      <el-tab-pane v-for="item in tabs"
                   :label="item.name"
                   :name="item"
                   :key="item.number"
      ></el-tab-pane>
    </el-tabs>
    <div class="middle-info">
      <div v-html="'生产时长'+formatMiddle(1)"></div>
      <el-divider direction="vertical" style="height: 3em" />
      <div v-html="'待机时长'+formatMiddle(0)"></div>
      <el-divider direction="vertical" style="height: 3em" />
      <div v-html="'报警时长'+formatMiddle(3)"></div>
      <el-divider direction="vertical" style="height: 3em" />
      <div v-html="'关机时长'+formatMiddle(2)"></div>
    </div>
    <el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center"/>
      <el-table-column label="日期" align="center" prop="date"/>
      <el-table-column label="设备名称" align="center" prop="name"/>
      <el-table-column label="设备编号" align="center" prop="number"/>
      <el-table-column label="运行时间" align="center" prop="runningTime" :formatter="formatSeconds"/>
      <el-table-column label="待机时间" align="center" prop="standbyTime" :formatter="formatSeconds"/>
      <el-table-column label="报警时间" align="center" prop="warningTime" :formatter="formatSeconds"/>
      <el-table-column label="关机时间" align="center" prop="shutdownTime" :formatter="formatSeconds"/>
      <el-table-column label="设备使用率" align="center" prop="utilization"
                       :formatter="(row, column, cellValue, index)=>{return  (parseFloat(cellValue) * 100.0).toFixed(2) + '%'}"/>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template #default="scope">
          <el-button type="primary" @click="trendClick(scope.row)">查看趋势图</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
        v-show="total>0"
        :total="total"
        :page-sizes="[200,500,1000]"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="getList"
    />
    <!-- 查看趋势图对话框-->
    <el-dialog :title="trendTitle" v-model="trendOpen" width="60%">
      <div class="echartsBox">
        <div
            id="echartDialogLeft"
            style="width:70%; height:450px">
        </div>
        <div
            id="echartDialogRight"
            style="width:30%; height:450px">
        </div>
      </div>
    </el-dialog>
    <!-- 添加或修改设备数据传输对话框 -->
    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
      <el-form ref="transactionRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="设备编号" prop="deviceNo">
          <el-input v-model="form.deviceNo" placeholder="请输入设备编号"/>
        </el-form-item>
        <el-form-item label="二进制数据" prop="data">
          <el-input v-model="form.data" placeholder="请输入二进制数据"/>
        </el-form-item>
        <el-form-item label="创建时间" prop="time">
          <el-date-picker clearable
                          v-model="form.time"
                          type="date"
                          value-format="YYYY-MM-DD"
                          placeholder="请选择创建时间">
          </el-date-picker>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="Transaction">
import {
  listTransaction,
  getTransaction,
  delTransaction,
  addTransaction,
  updateTransaction,
  getTrendList
} from "@/api/business/transaction";
import {parseTime} from "../../../utils/ruoyi";
import * as echarts from 'echarts'
import {onMounted, ref} from "vue";
import {listDept} from "../../../api/system/dept";
import {Search} from "@element-plus/icons-vue";
import {listDevice} from "../../../api/device";

const {proxy} = getCurrentInstance();

const daterangeCreateTime = ref([new Date().toISOString().substring(0, 10), new Date().toISOString().substring(0, 10)]);
const transactionList = ref({});
const tableData = ref([]);
const activeTab = ref();
const chartData = ref([]);
const open = ref(false);
const searchValue = ref('');
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const trendTitle = ref("");
const trendOpen = ref(false);
const trendList = ref([]);
const deptOptions = ref([]);
const checkedOptions = ref([])
const devs = ref([])
const tabs = ref([])
const selectPageTotal = ref(0)
const selectPageOption = reactive({
  deptId: null,
  pageNum: 1,
  pageSize: 15,
  name: '',
})

const data = reactive({
  form: {},
  queryParams: {
    deptId: null,
    pageNum: 1,
    pageSize: 200,
    deviceName: null,
    deviceNos: [],
  },
  rules: {
    deviceNo: [
      {required: true, message: "设备编号不能为空", trigger: "blur"}
    ],
    data: [
      {required: true, message: "二进制数据不能为空", trigger: "blur"}
    ],
    time: [
      {required: true, message: "创建时间不能为空", trigger: "blur"}
    ]
  }
});
//设备使用率曲线图配置选项
const option = reactive({
  tooltip: {
    trigger: 'axis',
    formatter: function (params) {
      var result = params[0].value[0] + '<br/>';
      params.forEach(function (item) {
        result += item.seriesName + ': ' + item.value[1] + '%<br/>';
      });
      return result;
    }
  },
  legend: {
    data: []
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  toolbox: {
    feature: {
      saveAsImage: {}
    }
  },
  xAxis: {
    type: 'time',
    minInterval: 3600 * 24 * 1000,
    axisLabel: {
      formatter: '{yyyy}-{MM}-{dd}'
    }
  },
  yAxis: {
    type: 'value'
  },
  series: []
})
//趋势图折线图配置
const stepDataOption = reactive({
  title: {},
  tooltip: {
    trigger: 'axis',
    formatter(params) {
      if (params[0].data[1] == 0) {
        return params[0].axisValue + '：关机状态'
      } else if (params[0].data[1] == 1) {
        return params[0].axisValue + '：待机状态'
      } else if (params[0].data[1] == 2) {
        return params[0].axisValue + '：工作状态'
      }
    },
    axisPointer: {},
  },
  legend: {},
  grid: {
    left: '3%',
    right: '4%',
    bottom: '8%',
    containLabel: true
  },
  toolbox: {
    feature: {
      dataView: {
        show: true,
        readOnly: false
      },
      restore: {
        show: true
      },
      saveAsImage: {
        show: true
      }
    },
    right: '2%'
  },
  dataZoom: [{
    type: 'inside',
    xAxisIndex: 0,
    start: 0,
    end: 100,

  }, {
    handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
    handleSize: '80%',
    handleStyle: {
      color: '#fff',
      shadowBlur: 3,
      shadowColor: 'rgba(0, 0, 0, 0.6)',
      shadowOffsetX: 2,
      shadowOffsetY: 2
    }
  }],
  xAxis: {
    type: 'category',
  },
  yAxis: {
    type: 'value',
    axisLine: {
      lineStyle: {
        color: '#999'
      }
    },
    min: 0,
    max: 2,
    splitNumber: 2,
    axisLabel: {
      color(value) {
        if (value == 0) {
          return '#303133'
        } else if (value == 1) {
          return '#409EFF'
        } else if (value == 2) {
          return '#67C23A'
        }
      },
      formatter(value) {
        if (value == 0) {
          return '关机状态'
        } else if (value == 1) {
          return '待机状态'
        } else if (value == 2) {
          return '工作状态'
        }
      },
    },

  },
  series: [
    {
      type: 'line',
      step: 'end',
      lineStyle: {
        color: '#3697FB'
      },
      data: [['12:00', 0], ['13:00', 1], ['14:00', 2], ['15:00', 1], ['16:00', 0], ['17:00', 2], ['18:00', 0]]
    },
  ]
})
//趋势图饼图配置
const pieDataOption = reactive({
  title: {
    left: 'center'
  },
  tooltip: {
    trigger: 'item',
    formatter(params) {
      let data = params.data.value * 3
      let day = Math.floor(data / (60 * 24))
      let hours = Math.floor((data % (60 * 24)) / 60)
      let minuntes = data % 60
      return params.data.name + '：' + day + '天' + hours + '时' + minuntes + '分' + '(' + params.percent + '%)'
    },
  },
  legend: {
    // orient: 'vertical',
    // top: 'middle',
    bottom: 10,
    left: 'center',
    data: []
  },
  series: [
    {
      type: 'pie',
      radius: '65%',
      color: ["#72E739", "#4A90E2", "#909399", "#AEFDCA", "#FFF065", "#FFAE8B", "#FF7DA1", "#F66BBF"],
      center: ['50%', '50%'],
      selectedMode: 'single',
      data: [
        {
          value: 8,
          name: "运行"
        },
        {
          value: 2,
          name: "关机"
        },
        {
          value: 2,
          name: "待机"
        }
      ],
      itemStyle: {
        emphasis: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
})
const {queryParams, form, rules} = toRefs(data);

onMounted(() => {
  listDept().then(response => {
    deptOptions.value = proxy.handleTree(response.data, "deptId");
  });
  getSelectingDevList(selectPageOption)

})
const handleClick = (tab) => {
  tableData.value = transactionList.value[tab.props.label]
}
//搜索设备
function searchDev(){
  checkedOptions.value.length = 0
  queryParams.value.deviceNos.length = 0
  selectPageOption.name = searchValue.value
  getSelectingDevList(selectPageOption)
}
function selectDev(value) {
  queryParams.value.deviceNos.length = 0
  value.forEach((item)=>{
    queryParams.value.deviceNos.push(item.number)
  })
}
//处理选择工厂
function handleChangeFactory(value) {
  checkedOptions.value.length = 0
  queryParams.value.deviceNos.length = 0
  selectPageOption.deptId = value
  getSelectingDevList(selectPageOption)
}
//获取下拉框设备列表
function getSelectingDevList(params) {
  listDevice(params).then((res)=>{
    devs.value = res.rows
    if (res.rows.length > 0){
      checkedOptions.value.push(res.rows[0])
      queryParams.value.deviceNos.push(res.rows[0].number)
      selectPageTotal.value = res.total
      getList()
    }
  })
}
//处理选择框分页
function handleSelectPageChange(pageNum) {
  selectPageOption.pageNum = pageNum
  getSelectingDevList(selectPageOption)
}
//查看趋势图
function trendClick(row) {
  trendOpen.value = true;
  trendTitle.value = row.name;
  getTrendList({date: row.date, deviceNo: row.number}).then((res) => {
    trendList.value = res.data
    initTrendChart(row)
  })
}

function initTrendChart(row) {
  nextTick(() => {
    let leftChart = echarts.init(document.getElementById('echartDialogLeft'));
    leftChart.clear()
    let rightChart = echarts.init(document.getElementById('echartDialogRight'));
    rightChart.clear()
    stepDataOption.series[0].data = trendList.value.map((item) => {
      return [item.time, item.data.substring(0, 1) === '1' ? 0 : (item.data.substring(1, 2) === '1' || item.data==='0000' ? 1 : 2)]
    })
    leftChart.setOption(stepDataOption)

    const temp = {}
    trendList.value.forEach((item)=>{
      let t = item.data.substring(0, 1) === '1' ? '关机' : (item.data.substring(1, 2) === '1' || item.data==='0000' ? '待机' : '运行')
      if (temp[t]){
        temp[t]['value'] ++
      }else{
        temp[t] = {
          value: 1,
          name: t,
        }
      }
    })
    if (row.count2 !== 0){
      let r = temp['运行'] ? temp['运行']['value'] : 0
      let g = temp['待机'] ? temp['待机']['value'] : 0
      temp['关机'] = {
        value: r + g < 24*60/3 ? 24*60/3 - r - g : 0,
        name: '关机',
      }
    }

    pieDataOption.series[0].data = Object.values(temp)
    rightChart.setOption(pieDataOption)
  })

}

//初始化图表
function initChart() {

  const chart = echarts.init(document.getElementById('chart-middle'));
  chart.clear()
  // 处理数据，按照name分组
  var seriesData = {};
  chartData.value.forEach(function (item) {
    if (!seriesData[item.name]) {
      seriesData[item.name] = {
        name: item.name,
        type: 'line',
        data: []
      };
    }
    seriesData[item.name].data.push({
      value: [item.date, (parseFloat(item.utilization)*100).toFixed(2)]
    });
  });
  // 将分组后的数据转换为ECharts需要的数组格式
  var series = [];
  for (var key in seriesData) {
    series.push(seriesData[key]);
  }
  option.legend.data = Object.keys(seriesData)
  option.series = series;
  chart.setOption(option)
}

//格式化列表日期
function formatSeconds(row, column, cellValue, index) {
  let data = cellValue / (60)
  let day = Math.floor(data / (60 * 24))
  let hours = Math.floor((data % (60 * 24)) / 60)
  let minuntes = data % 60
  return day + '天' + hours + '时' + minuntes + '分'
}

/** 查询设备数据传输列表 */
function getList() {
  loading.value = true;
  queryParams.value.params = {};
  if (null != daterangeCreateTime && '' != daterangeCreateTime) {
    queryParams.value.params["beginCreateTime"] = daterangeCreateTime.value[0];
    queryParams.value.params["endCreateTime"] = daterangeCreateTime.value[1];
  }
  listTransaction(queryParams.value).then(response => {
    //tableData.value = response.rows;
    chartData.value = response.rows;
    transactionList.value = {}
    response.rows.forEach((item)=>{
      if (transactionList.value[item.name]){
        transactionList.value[item.name].push(item)
      }else {
        transactionList.value[item.name]= [item]
      }
    })
    total.value = response.total;
    loading.value = false;
    tabs.value = checkedOptions.value //标签页
    activeTab.value = tabs.value[0]
    tableData.value = transactionList.value[activeTab.value.name]
    initChart()
  });
}

// 取消按钮
function cancel() {
  open.value = false;
  reset();
}

// 表单重置
function reset() {
  form.value = {
    id: null,
    deviceNo: null,
    data: null,
    time: null
  };
  proxy.resetForm("transactionRef");
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}

/** 重置按钮操作 */
function resetQuery() {
  proxy.resetForm("queryRef");
  handleQuery();
}

// 多选框选中数据
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
}

/** 新增按钮操作 */
function handleAdd() {
  reset();
  open.value = true;
  title.value = "添加设备数据传输";
}

/** 修改按钮操作 */
function handleUpdate(row) {
  reset();
  const _id = row.id || ids.value
  getTransaction(_id).then(response => {
    form.value = response.data;
    open.value = true;
    title.value = "修改设备数据传输";
  });
}

/** 提交按钮 */
function submitForm() {
  proxy.$refs["transactionRef"].validate(valid => {
    if (valid) {
      if (form.value.id != null) {
        updateTransaction(form.value).then(response => {
          proxy.$modal.msgSuccess("修改成功");
          open.value = false;
          getList();
        });
      } else {
        addTransaction(form.value).then(response => {
          proxy.$modal.msgSuccess("新增成功");
          open.value = false;
          getList();
        });
      }
    }
  });
}

/** 删除按钮操作 */
function handleDelete(row) {
  const _ids = row.id || ids.value;
  proxy.$modal.confirm('是否确认删除设备数据传输编号为"' + _ids + '"的数据项？').then(function () {
    return delTransaction(_ids);
  }).then(() => {
    getList();
    proxy.$modal.msgSuccess("删除成功");
  }).catch(() => {
  });
}

/** 导出按钮操作 */
function handleExport() {
  proxy.download('business/transaction/export', {
    ...queryParams.value
  }, `transaction_${new Date().getTime()}.xlsx`)
}
function formatMiddle(type) {
  let time = 0;
  let totalTime = 0;
  tableData.value.forEach((item)=>{totalTime += (item.standbyTime+item.runningTime+item.shutdownTime)})
  switch (type) {
    //待机
    case  0:
      tableData.value.forEach((item)=>{time += item.standbyTime});break;
    //生产
    case  1:
      tableData.value.forEach((item)=>{time += item.runningTime});break;
    //关机
    case  2:
      tableData.value.forEach((item)=>{time += item.shutdownTime});break;
    //报警
    case  3:
      tableData.value.forEach((item)=>{time += item.warningTime});break;
  }
  let data = time / (60)
  let day = Math.floor(data / (60 * 24))
  let hours = Math.floor((data % (60 * 24)) / 60)
  let minuntes = data % 60
  const str = '<br>' + day + '天' + hours + '时' + minuntes + '分<br>占比' + (time / totalTime * 100).toFixed(2) + '%'
  return str
}
</script>
<style>
.echartsBox {
  display: flex;
}

.DropDownPopBox {
  box-sizing: border-box;
  padding: 16px;
  padding-bottom: 0;
  position: relative;
}

.middle-info {
  height: 70px;
  display: flex;
  align-items: center;
  justify-content: space-around;
  text-align: center;
}
</style>
